package controller

import (
	"errors"
	"ginfast/api/system/dto"
	"ginfast/api/system/model"
	"ginfast/middleware"
	"ginfast/pkg/dao"
	"ginfast/pkg/gctx"
	"ginfast/util"

	"github.com/gin-gonic/gin"
)

// Role 系统角色
type Role struct {
}

// ListHandler 列表
func (Role) ListHandler(c *gin.Context) {
	var p dto.Where
	if err := c.ShouldBind(&p); err != nil {
		gctx.JSONWriteError(err, c)
		return
	}
	t := middleware.GetUserToken(c)
	if t.UserName != model.SysUserName {
		p.CreatedBy = t.UserName
	}
	var data []model.SysRole
	total, _ := p.DbModelWhere(&model.SysRole{}).Find(&data)
	gctx.JSONWrite(gin.H{"data": data, "total": total}, c)
}

// GetHandler 查询
func (Role) GetHandler(c *gin.Context) {
	id := gctx.ParamUInt(c, "id")
	var role model.SysRole
	if err := dao.DbFirstById(&role, id); err != nil {
		gctx.JSONWriteError(err, c)
		return
	}
	gctx.JSONWriteData(role.SysRoleOpt, c)
}

func (Role) AllocatedListPageHandler(c *gin.Context) {
	var p dto.Where
	if err := c.ShouldBind(&p); err != nil {
		gctx.JSONWriteError(err, c)
		return
	}
	var data []model.SysUser
	total, _ := p.DbModelWhere(&model.SysRole{}, func(dw *dao.DbWhere) {
		dw.Add("role_id = ?", p.RoleId)
	}).Find(&data)
	gctx.JSONWrite(gin.H{"data": data, "total": total}, c)
}

// 获取当前登录用户创建的用户并且角色不为roleId
func (Role) UnAllocatedListPageHandler(c *gin.Context) {
	var p dto.Where
	if err := c.ShouldBind(&p); err != nil {
		gctx.JSONWriteError(err, c)
		return
	}
	p.CreatedBy = middleware.GetUserToken(c).UserName
	var data []model.SysUser
	total, _ := p.DbModelWhere(&model.SysRole{}, func(dw *dao.DbWhere) {
		dw.Add("role_id != ?", p.RoleId)
	}).Find(&data)
	gctx.JSONWrite(gin.H{"data": data, "total": total}, c)
}

// AddHandler 新增
func (Role) AddHandler(c *gin.Context) {
	var p model.SysRole
	//获取参数
	if err := c.ShouldBind(&p.SysRoleOpt); err != nil {
		gctx.JSONWriteError(err, c)
		return
	}
	if err := dao.DbFirstBy(&p, "name = ? || key = ?", p.Name, p.Key); err == nil {
		gctx.JSONWriteError(errors.New("role record exist"), c)
		return
	}
	p.CreatedBy = middleware.GetUserToken(c).UserName
	p.DataScope = "1"
	if err := dao.DbCreate(&p); err != nil {
		gctx.JSONWriteError(err, c)
		return
	}
	gctx.JSONOK(c)
}

// UpdateHandler 修改
func (Role) UpdateHandler(c *gin.Context) {
	var p model.SysRole
	if err := c.ShouldBind(&p.SysRoleOpt); err != nil {
		gctx.JSONWriteError(err, c)
		return
	}
	p.UpdatedBy = middleware.GetUserToken(c).UserName
	// 更新数据
	if err := dao.DbUpdateById(&p, p.ID); err != nil {
		gctx.JSONWriteError(err, c)
		return
	}
	gctx.JSONOK(c)
}

// ChangeStatusHandler 改变角色状态
func (Role) ChangeStatusHandler(c *gin.Context) {
	var p model.SysRole
	//获取参数
	if err := c.ShouldBind(&p.SysRoleOpt); err != nil {
		gctx.JSONWriteError(err, c)
		return
	}
	if err := dao.DbUpdateColById(model.SysRole{}, p.ID, "status", p.Status); err != nil {
		gctx.JSONWriteError(err, c)
		return
	}
	gctx.JSONOK(c)
}

type roleSelectAuth struct {
	UserIds string `fdao:"userIds"` // 菜单状态
	RoleId  uint64 `fdao:"roleId"`  // 菜单状态
}

// AuthSelectAllHandler 修改
func (Role) AuthSelectAllHandler(c *gin.Context) {
	var p roleSelectAuth
	if err := c.ShouldBind(&p); err != nil {
		gctx.JSONWriteError(err, c)
		return
	}
	userIds := util.StringToIntSlice(p.UserIds, ",")
	if err := dao.DbUpdateByIds(&model.SysUser{}, userIds, dao.H{"role_id": p.RoleId}); err != nil {
		gctx.JSONWriteError(err, c)
		return
	}
	gctx.JSONOK(c)
}

type roleCancelAuth struct {
	UserId uint64 `fdao:"userId"` // 菜单状态
	RoleId string `fdao:"roleId"` // 菜单状态
}

// AuthCancelHandler
func (Role) AuthCancelHandler(c *gin.Context) {
	var p roleCancelAuth
	if err := c.ShouldBind(&p); err != nil {
		gctx.JSONWriteError(err, c)
		return
	}
	if err := dao.DbUpdateColById(&model.SysUser{}, p.UserId, "role_id", 0); err != nil {
		gctx.JSONWriteError(err, c)
		return
	}
	gctx.JSONOK(c)
}

// DeleteHandler 删除角色
func (Role) DeleteHandler(c *gin.Context) {
	dao.Deletes(&model.SysRole{}, c)
}

func (o Role) Router(r *gin.RouterGroup) {
	r.GET("/list", o.ListHandler)
	r.GET("/:id", o.GetHandler)
	r.GET("/authUser/allocatedList", o.AllocatedListPageHandler)
	r.GET("/authUser/unallocatedList", o.UnAllocatedListPageHandler)
	r.POST("", o.AddHandler)
	r.PUT("/changeStatus", o.ChangeStatusHandler)
	r.PUT("", o.UpdateHandler)
	r.PUT("/authUser/selectAll", o.AuthSelectAllHandler)
	r.PUT("/authUser/cancel", o.AuthCancelHandler)
	r.DELETE("/:id", o.DeleteHandler)
}
